home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / pausedev.zip / PAUSEDEV.PAS < prev   
Pascal/Delphi Source File  |  1993-01-23  |  4KB  |  142 lines

  1.   {$S-,F-}         { Stack checking wouldn't work here, and we assume near calls
  2. }
  3.   {$X+}            { Extended syntax }
  4.   {$M $1000,0,0}   { We won't use the heap or stack. }
  5.  
  6.   program pausedev;
  7.   { This program implements a PAUSE command either as DEVICE=PAUSEDEV.EXE
  8.     or executed from the command line. }
  9.  
  10.   uses opint,  { OPro interrupt services, needed for stack switching }
  11.        crt;    { Standard I/O unit that doesn't rely on DOS }
  12.  
  13.   procedure strategy_routine(bp:word); interrupt; forward;
  14.   procedure interrupt_routine(bp:word); interrupt; forward;
  15.   procedure call_Main_Block; forward;
  16.  
  17.   { This procedure must come first!!! }
  18.  
  19.   procedure header;
  20.   assembler;
  21.   asm
  22.     dd $FFFFFFFF    { next driver }
  23.     dw $8000        { attributes of simple character device }
  24.     dw offset strategy_routine
  25.     dw offset interrupt_routine
  26.     db 'PAUSE   '
  27.   end;
  28.  
  29.   const
  30.     stDone = $100;
  31.     stBusy = $200;
  32.  
  33.     cmInit = 0;
  34.  
  35.     device_driver : boolean = false;
  36.  
  37.   type
  38.     request_header = record
  39.       request_length : byte;
  40.       subunit: byte;
  41.       command_code : byte;
  42.       status : word;
  43.       reserved: array[1..8] of byte;
  44.       num_units : byte;
  45.       first_free : pointer;
  46.       args : ^char;
  47.       drive_num : byte;
  48.     end;
  49.  
  50.   var
  51.     local_stack : array[1..4000] of byte;
  52.     end_of_stack : byte;
  53.     request : ^request_header;
  54.  
  55.   procedure handler(var regs : intregisters);
  56.   { This routine is called by the strategy routine, and handles all requests.
  57.     The data segment is okay, and we're running on the local_stack so we've got
  58.     plenty of space.  Remember:  the init sections haven't been called yet!
  59.   }
  60.   begin
  61.     with request^ do
  62.     begin
  63.       case command_code of
  64.       cmInit: begin
  65.                 device_driver := true;
  66.                 Call_Main_Block;
  67.                 first_free := ptr(cseg,0); { Release everything!! }
  68.                 status := stDone;
  69.               end;
  70.       else
  71.         status := stBusy;
  72.       end;
  73.     end;
  74.   end;
  75.  
  76.   procedure RetFar; assembler;
  77.   { Replacement for the IRET code that ends the interrupt routines below }
  78.   asm
  79.     mov sp,bp
  80.     pop bp
  81.     pop es
  82.     pop ds
  83.     pop di
  84.     pop si
  85.     pop dx
  86.     pop cx
  87.     pop bx
  88.     pop ax
  89.     retf
  90.   end;
  91.  
  92.   procedure strategy_routine(bp:word);
  93.   var
  94.     regs : intregisters absolute bp;
  95.   begin
  96.     with regs do
  97.       request := ptr(es,bx);
  98.     RetFar;
  99.   end;
  100.  
  101.   procedure interrupt_routine(bp:word);
  102.   var
  103.     regs : intregisters absolute bp;
  104.   begin
  105.     SwapStackandCallNear(Ofs(handler),@end_of_stack,regs);
  106.     RetFar;
  107.   end;
  108.  
  109.   procedure do_pause;
  110.   begin
  111.     while keypressed do readkey;
  112.     writeln('Press any key to continue....');
  113.     repeat until keypressed;
  114.   end;
  115.  
  116.   procedure Ret_From_Main_Block; assembler;  { Must have declaration just
  117.                                                 like Call_Main_Block }
  118.   asm
  119.   end;
  120.  
  121.   procedure Call_Main_Block; assembler;      { Must come just before main
  122.                                                   entry point }
  123.   asm
  124.     db $eb, 6                                { Jump over the Ret instruction
  125.                                                and System init }
  126.   end;
  127.  
  128.   begin
  129.     do_pause;
  130.  
  131.     if Device_Driver then
  132.       asm
  133.         pop bp
  134.         jmp Ret_From_Main_Block;
  135.       end
  136.     else
  137.       halt;
  138.  
  139.     header;    { This line is never reached, but it fools the linker
  140.                  so that everything is loaded properly. }
  141.   end.
  142.